package com.tanhua.dubbo.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.dubbo.utils.TimeLineService;
import com.tanhua.model.mongo.Friend;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.MovementTimeLine;
import com.tanhua.model.vo.PageResult;
import net.sf.jsqlparser.statement.upsert.Upsert;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.checkerframework.checker.units.qual.A;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.MatchOperation;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.List;

@DubboService
public class MovementApiImpl implements MovementApi {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private TimeLineService timeLineService;
    @Override   //保存发布的动态  数据存在动态表，查询好友，
    public String saveMovement(Movement movement) {
        //保存动态详情到动态表,保存完之后movement对象里会自动得到id，用于保存在关系表
        timeLineService.saveTimeLine(movement);
        mongoTemplate.save(movement);
        ObjectId id = movement.getId();
        //返回string类型的动态id
        String string = id.toString();
        return string;
    }

    @Override  //查所有动态
    public List<Movement> findAll(Integer page, Integer pageSize, Long userId) {
        Criteria criteria = Criteria.where("userId").is(userId).and("state").is(1);
        //从高到底排序，每次查limit条，从skip条开始查
        Query query = Query.query(criteria).with(Sort.by(Sort.Order.desc("created"))).skip(pageSize*(page-1)).limit(pageSize);
//        long count = mongoTemplate.count(query, Movement.class);
//        System.out.println("共查出"+count);
        List<Movement> movements = mongoTemplate.find(query, Movement.class);
        return movements;
    }

    //查好友动态
    public List<Movement> friendsMovement(Integer page, Integer pageSize, Long userId) {
        //根据userId查询动态关系表
        Criteria criteria = Criteria.where("friendId").is(userId);
        Query query = Query.query(criteria).with(Sort.by(Sort.Order.desc("created"))).skip((page - 1) * pageSize).limit(pageSize);
        List<MovementTimeLine> lines = mongoTemplate.find(query, MovementTimeLine.class);//第二部分写要查询哪个表
      //  ArrayList<ObjectId> objectIds = new ArrayList<>();
//        for (MovementTimeLine timeLine : lines) {
//            ObjectId movementId = timeLine.getMovementId();
//            objectIds.add(movementId);
//        }
        //从list集合提取对象的某个属性  三个参数，提取所有动态id
        List<ObjectId> ids = CollUtil.getFieldValues(lines, "movementId", ObjectId.class);
//        if (CollectionUtil.isEmpty(objectIds)){
//            return new ArrayList<Movement>();
//        }
      //查询动态表，根据动态id查询所有动态数据对象
        Criteria criteria1 = Criteria.where("id").in(ids).and("state").is(1);//is相当于mysql中的
        Query query1 = Query.query(criteria1).with(Sort.by(Sort.Order.desc("created")));
       return mongoTemplate.find(query1,Movement.class);
    }

    //根据redis中得推荐数据查动态
    public List<Movement> findByIds(String[] ids, Integer page, Integer pageSize) {
        Criteria criteria = Criteria.where("id").in(ids).and("state").is(1);//不需要排序,推荐动态
        Query query = Query.query(criteria).limit(pageSize).skip((page - 1) * pageSize);
        List<Movement> movements = mongoTemplate.find(query, Movement.class);
        return movements;
    }

    @Override   //随机查询推荐动态数据
    public List<Movement> randomMovement(Integer pageSize) {
        //本质：采样，随机读取  参数：采样配置(采集数量)  返回实体类类型
        //设置查询条件
        Criteria criteria = Criteria.where("state").is(1);
        MatchOperation match = Aggregation.match(criteria);
        //1.设置采样数量
        TypedAggregation<Movement> aggregation = TypedAggregation.newAggregation(Movement.class, match,Aggregation.sample(pageSize));
          //2.采样后把结果封装在对象中
        AggregationResults<Movement> results = mongoTemplate.aggregate(aggregation, Movement.class);
        //3.从采样结果中获取采样数据
        List<Movement> list = results.getMappedResults();
        return list;
    }

    @Override
    public Movement findById(String id) {
        return mongoTemplate.findById(id,Movement.class);
    }

    @Override  //审核动态内容 更新状态
    public void update(String movementId, int stats) {
        Criteria criteria = Criteria.where("id").is(new ObjectId(movementId));
        Query query = Query.query(criteria);
        Update update = new Update();
        update.set("state",stats);
        mongoTemplate.updateFirst(query,update,Movement.class);
    }

    //查询某用户的动态列表,状态或id可能不传，所以判断在设置条件
    public PageResult findMovementList(Integer status, Integer page, Integer pageSize, Long uid) {
        Query query = new Query();
        if(uid!=null){
            query.addCriteria(Criteria.where("userId").is(uid));
        }
        if (status!=null){
            query.addCriteria(Criteria.where("state").is(status));
        }
        long count = mongoTemplate.count(query, Movement.class);
        query.with(Sort.by(Sort.Order.desc("created"))).skip((page-1)*pageSize).limit(pageSize);
        List<Movement> movements = mongoTemplate.find(query, Movement.class);
        return new PageResult(page,pageSize,count,movements);
    }

}
